<template>
    <div class="flex flex-col w-full h-full">
        <main ref="contentRef" class="flex-1 overflow-hidden overflow-y-auto">
            <div ref="scrollRef" :class="[isMobile ? 'p-2':'p-5']"
                class="w-full max-w-screen-3xl m-auto">
                <Message v-for="(item,index) of messages"
                    :key="index"
                    :class="messages.length-1 == index ? '!mb-2':'mb-6'"
                    :createTime="item.createTime"
                    :error="item.isError"
                    :inversion="item.role !=='assistant'"
                    :loading="loading"
                    :text="item.message"
                    @delete="handleDelete(item)"
                />
            </div>
        </main>
        <footer class="p-4">
            <div class="w-full max-w-screen-3xl m-auto pb-6 relative">

                <AutoSizeTextArea
                    v-model="message" placeholder="请输入您的问题"
                    @keypress="handleEnter">
                <template #suffix>
                    <el-button v-if="!loading"  type="primary" @click="handleSubmit" class="suffix-button"
                        size="large" text>
                        <SvgIcon :name="'mdi:sparkles-outline'" :iconify="true" class="text-[14px]"/>
                    </el-button>
                    <el-button v-if="loading"  type="primary" @click="handleStop"  class="suffix-button"
                        size="large" text>
                        <SvgIcon :name="'ri:stop-circle-line'" :iconify="true" class="text-[14px]"/>
                    </el-button> 
                </template>
                </AutoSizeTextArea>
            </div>
        </footer>
    </div>
</template>

<script lang="ts" setup>
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { v4 as uuidv4 } from 'uuid';
import { useI18n } from 'vue-i18n';
import AutoSizeTextArea from '/@/components/TextArea/index.vue';
import { useMessage, useMessageBox } from '/@/hooks/message';
import { useChatStore } from '/@/stores/aigc/chatStore';
import { useScroll } from '/@/stores/aigc/useScroll';
import { Session } from '/@/utils/storage';
import Message from './message/message.vue';
    const { t } = useI18n();
    const chatStore = useChatStore();
    const { contentRef, scrollRef, scrollToTop, scrollToBottom, scrollToBottomIfAtBottom}=useScroll();
    const loading = ref<boolean>(false);
    const chatId=ref("");
    const aiChatId=ref("");
    const message=ref("");

    const isMobile=ref(false);

    let controller = new AbortController();
    const messages=computed(()=>{
        scrollToBottom();
        return chatStore.messages;
    });
    const handleEnter=(event:KeyboardEvent)=>{
        if(!isMobile.value){
            if(event.key ==='Enter' && !event.shiftKey){
                event.preventDefault();
                handleSubmit();
            }
        }else{
            if(event.key ==='Enter' && event.ctrlKey){
                event.preventDefault();
                handleSubmit();
            }
        }
    }

    const handleSubmit=async ()=>{
        const msg=message.value;
        if(loading.value){
            return;
        }
        if(!msg||msg.trim()===""){
            useMessage().error(t('chat.inputMessageTip'));
            return;
        }
        controller = new AbortController();

        chatId.value=uuidv4();
        await chatStore.addMessage( msg,'user',chatId.value);
        loading.value=true;
        message.value="";

        await scrollToBottom();
        aiChatId.value=uuidv4();
        await chatStore.addMessage("",'assistant',aiChatId.value);
        await scrollToBottomIfAtBottom();

        await onChat(msg);
    }

    const onChat=async (message:string)=>{
        let chatReq={
            chatId:chatId.value,
            appId:chatStore.appId,
            conversationId:chatStore.conversationId,
            modelId:chatStore.modelId,
            message:message,
            role:'user'
        };

        //为传递controller则新建一个
        const controller=new AbortController();
        //流式调用
        const baseURL=import.meta.env.VITE_API_URL;
        //消息内容
        let messageContent="";
        //发起流式请求，并监听事件
        fetchEventSource(baseURL+'/aigc/chat/completions', {
            headers: {
                'Content-Type': 'application/json',
                //避免错误时无法捕获错误信息
                Accept: '*/*',
                'Authorization': `Bearer ${Session.getToken()}`,
                'TENANT-ID': Session.getTenant(),
                // 其他需要的头部信息...
            },
            method: 'post',
            signal:controller.signal,
            body:JSON.stringify(chatReq),
            openWhenHidden: true,
            onopen:async(response)=> {
                console.log('连接已打开');
                if(response.ok){
                    const contentType = response.headers.get('Content-Type');
                    //判断是否流式响应
                    if(!contentType?.startsWith('text/event-stream')){
                       //使用.json获取数据
                       const errorData=response.json() as ErrorResponse;
                       console.error('发生错误:', errorData);
                       //捕获的响应体
                       if(errorData?.code===202&& !errorData?.success){
                          //错误处理逻辑
                          controller.abort();
                          loading.value=false;
                          return;
                       }
                    }
                }else{
                    controller.abort();
                    loading.value=false;
                    console.error('发生错误:', response);
                    return;
                }
            },
            onmessage(event) {
                console.log('收到消息', event);
                const data = event.data;
                if(data==='[DONE]'||data===''){
                    console.log('完成');
                    messageComplete(messageContent,false);
                    return;
                }
                //处理流式数据
                try{
                    //尝试解析为json对象
                    const jsonData=JSON.parse(data);
                     // 如果等于stop表示结束
                    if (jsonData.choices[0]?.finish_reason === 'stop') {
                        console.log('完成');
                        messageComplete(messageContent,false);
                        return;
                    }
                   messageContent+=jsonData?.choices?.[0]?.delta?.content||'';
                   chatStore.updateMessage(aiChatId.value,messageContent);
                }catch(e){
                    console.error('无法解析消息', e);
                     messageComplete(true);
                }finally{
                    scrollToBottomIfAtBottom();
                }
            },
            onclose() {
                console.log('连接已关闭');
                loading.value=false;
                messageComplete(messageContent,false);
            },
            onerror(err) {
                controller.abort();
                console.error('发生错误:', err);
                loading.value=false;
                messageComplete(messageContent,true);
            },
        });

    }
    //消息完成处理方法抽取
    const messageComplete=(messageContent:string,isError:boolean)=>{
        if(messageContent!=""){
            chatStore.updateMessage(aiChatId.value,messageContent,isError);
            messageContent="";
        }
    }
    //停止生成
    const handleStop=()=>{
        if(loading.value){
            controller.abort();
            controller = new AbortController();
            loading.value=false;
        }
    }
    const handleDelete=(item:any)=>{
        useMessageBox().confirm(t('common.delBtn')).then(()=>{
            chatStore.deleteMessage(item.chatId);
        });
    }

</script>

<style scoped>
    ::v-deep(.custom-input){
        .el-input__wrapper{
            padding-right: 6px !important;
        }
    }
    
    .textarea-wrapper {
        border: 2px  solid #ccc;
        display: flex;
        align-items: flex-end; /* 确保按钮垂直居中 */
    }
    textarea {
        flex-grow: 1; /* 让 textarea 占据剩余空间 */
        margin-right: 10px; /* 为按钮留出空间 */
        overflow-y: hidden;/*隐藏滚动条*/
        resize: none;/*取消小三角*/
    }
</style>